#[allow(static_mut_refs)]
#[allow(unused_imports)]
mod bindings;

use crate::bindings::exports::pa_ck::na_me_exports::component_name_api::*;
use std::cell::RefCell;
use bytes::{Buf, BufMut, Bytes};

// Import for using common lib (also see Cargo.toml for adding the dependency):
// use common_lib::example_common_function;

/// This is one of any number of data types that our application
/// uses. Golem will take care to persist all application state,
/// whether that state is local to a function being executed or
/// global across the entire program.
struct State {
    total: u64,
}

thread_local! {
    /// This holds the state of our application.
    static STATE: RefCell<State> = RefCell::new(State {
        total: 0,
    });
}

struct Component;

impl Component {
    fn set(value: u64) {
        STATE.with_borrow_mut(|state| {
            state.total = value;
        })
    }
}

impl Guest for Component {
    /// Updates the component's state by adding the given value to the total.
    fn add(value: u64) {
        STATE.with_borrow_mut(|state| state.total += value);
    }

    /// Returns the current total.
    fn get() -> u64 {
        // Call code from shared lib
        // println!("{}", example_common_function());

        STATE.with_borrow(|state| state.total)
    }
}


impl golem_rust::save_snapshot::exports::golem::api::save_snapshot::Guest for Component {
    fn save() -> Vec<u8> {
        let mut result = Vec::new();
        result.put_u64(Component::get());
        result
    }
}

impl golem_rust::load_snapshot::exports::golem::api::load_snapshot::Guest for Component {
    fn load(bytes: Vec<u8>) -> Result<(), String> {
        if bytes.len() >= 8 {
            Component::set(Bytes::from(bytes).get_u64());
            Ok(())
        } else {
            Err("Invalid snapshot - not enough bytes to read u64".to_string())
        }
    }
}

bindings::export!(Component with_types_in bindings);

golem_rust::save_snapshot::export_save_snapshot!(Component with_types_in golem_rust::save_snapshot);
golem_rust::load_snapshot::export_load_snapshot!(Component with_types_in golem_rust::load_snapshot);
